昨天先從 System Design 的基本觀念開始,理解了 scalability、latency、throughput,以及 consistency / availability 之間的取捨。
今天我想先回到一個看起來很基本,但其實後面所有 Web System Design 都會用到的問題:
當我在瀏覽器輸入
https://example.com並按下 Enter 之後,到底發生了什麼?
以前在寫前後端時,我對這件事的理解大概只有「瀏覽器送 Request,Server 回 Response」。但如果要開始學 Load Balancer、Reverse Proxy、CDN、API Gateway,至少要先知道一個 Request 原本是怎麼走到 Server 的。
所以 Day 2 先把整條 Request Flow 串起來。
假設在瀏覽器輸入:
https://example.com/users/123
可以先把流程簡化成:
Browser
↓
解析 URL
↓
DNS Lookup
example.com → IP Address
↓
建立 TCP Connection
↓
HTTPS:建立 TLS 加密連線
↓
HTTP Request
↓
Server
↓
HTTP Response
↓
Browser
這篇先不深入 CDN、Load Balancer、Reverse Proxy,而是專注在最基本的:
我們平常輸入的是:
example.com
但網路真正傳送資料時,需要知道目標 Server 的 IP Address。
因此第一步通常會是:
example.com
↓ DNS
93.184.x.x
可以把 DNS 想成網路世界的電話簿:
Domain Name
↓
IP Address
人類比較容易記 google.com,電腦則需要知道實際要把封包送到哪個 IP。
先看最基本的 DNS 查詢流程:
Browser
↓
DNS Resolver
↓
Root Name Server
↓
TLD Name Server
↓
Authoritative Name Server
↓
IP Address
以 www.example.com 為例,可以粗略理解成:
Resolver:誰知道 .com?
↓
Root Server:去問 .com 的 TLD Server
↓
TLD Server:example.com 的 DNS Server 在這裡
↓
Authoritative DNS:www.example.com 對應到這個 IP
實務上不一定每次都會完整走完這條流程,因為 DNS 結果通常會被 Cache。
Domain 對應到 IPv4:
example.com
↓
93.184.x.x
Domain 對應到 IPv6。
把一個 Domain 指向另一個 Domain:
www.example.com
↓
example.com
TTL 可以決定 DNS Record 可以被 Cache 多久。
也就是說:
第一次查 DNS
↓
拿到結果
↓
Cache 一段時間
↓
後續不用每次重新查詢
這也是為什麼修改 DNS 設定後,通常不一定會馬上在所有地方生效。
知道 Server IP 之後,Client 還需要建立連線。
先用三層來理解今天的網路模型:
HTTP
──────────── Application Layer
TCP
──────────── Transport Layer
IP
──────────── Network Layer
可以非常粗略地理解成:
HTTP
「我要 GET /users/123」
TCP
「我負責可靠地把資料送過去」
IP
「我要把 Packet 送到哪一台機器」
TCP 是 connection-oriented protocol。
在開始傳資料之前,Client 和 Server 會先建立 Connection:
Client Server
─────── SYN ──────────>
<──── SYN + ACK ───────
─────── ACK ──────────>
Connection
Established
這就是常聽到的 TCP Three-way Handshake。
TCP 提供的重點包括:
如果某些 Packet 在傳輸過程中遺失,TCP 可以協助重新傳送。
Day 2 先知道差異即可:
| TCP | UDP |
|---|---|
| Connection-oriented | Connectionless |
| 可靠傳輸 | 不保證送達 |
| 保證順序 | 不保證順序 |
| Overhead 較高 | Overhead 較低 |
HTTP/1.1 與 HTTP/2 通常建立在 TCP 之上。
如果網址是:
http://example.com
主要就是 HTTP 傳輸。
如果是:
https://example.com
則會多一層 TLS 保護:
Client
↓
TLS Encrypted Connection
↓
Server
可以先把 HTTPS 理解成:
HTTP 的資料透過 TLS 加密後再進行傳輸。
Day 2 先記住:
80
443
至於 RSA、ECDHE、Certificate Chain 等密碼學細節,先不展開。
TCP / TLS Connection 建立好之後,Browser 就可以送 HTTP Request。
例如:
GET /users/123 HTTP/1.1
Host: example.com
Accept: application/json
一個 HTTP Request 可以先拆成:
Method
Path
Headers
Body(不一定有)
常見 Method:
GET → 取得資料
POST → 建立資料
PUT → 更新 / 替換資料
PATCH → 部分更新
DELETE → 刪除資料
例如:
GET /users/123
代表 Client 想要取得 /users/123 這個 Resource。
Server 收到 Request、處理完之後,就會回傳 Response。
例如:
HTTP/1.1 200 OK
Content-Type: application/json
{
"name": "Brian"
}
HTTP Response 可以拆成:
Status Code
Headers
Body
常見 Status Code:
2xx → Success
200 OK
201 Created
3xx → Redirect
301 Moved Permanently
302 Found
4xx → Client Error
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
5xx → Server Error
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
不用一次背完,先知道每個區間代表的類型就夠了。
現在再重新看一次:
https://example.com/users/123
完整流程可以理解成:
1. Browser 解析 URL
2. DNS Lookup
example.com
↓
IP Address
3. Browser 取得 Server IP
4. Client 與 Server 建立 TCP Connection
5. 因為使用 HTTPS
建立 TLS Encrypted Connection
6. Browser 發送 HTTP Request
GET /users/123
7. Server 收到並處理 Request
8. Server 回傳 HTTP Response
200 OK
Headers
Body
9. Browser 收到 Response
只要能把這條路徑講清楚,後面開始加入 Load Balancer、Reverse Proxy、CDN 時就會容易很多。
今天我也做了幾個很簡單的實驗,把抽象概念對應到實際工具。
dig 查 DNSdig google.com
也可以試:
dig github.com
dig openai.com
主要觀察:
Domain
↓
IP Address
Mac / Linux 也可以使用:
nslookup google.com
curl -v 看 HTTP Request / Responsecurl -v https://example.com
輸出裡可以看到類似:
> GET /
> Host: example.com
> User-Agent: ...
> 代表送出的 Request。
另外也會看到:
< HTTP/2 200
< content-type: text/html
< content-length: ...
< 代表 Server 回傳的 Response。
這個指令很適合拿來把 HTTP Request / Response 從課本概念變成真的東西。
在 Chrome 開啟:
Inspect
→ Network
→ Reload
點選任一 Request,可以看到:
以前打開 DevTools 時我通常只看 API 有沒有 200,但理解今天的流程後,Network 頁面其實就是把 HTTP Request / Response 很直接地呈現出來。
Day 2 我最想記住的不是所有 DNS Record 或 HTTP Status Code,而是整條資料流:
URL
↓
DNS
↓
IP
↓
TCP
↓
TLS
↓
HTTP Request
↓
Server
↓
HTTP Response
其中每一層負責的事情不同:
| 元件 | 主要功能 |
|---|---|
| DNS | Domain Name → IP Address |
| IP | 決定資料要送去哪台機器 |
| TCP | 提供可靠、有順序的傳輸 |
| TLS | 加密 Client 與 Server 間的資料 |
| HTTP | 定義 Client / Server 如何交換 Request 與 Response |
這條路徑之後還會逐漸被插入更多 System Design 元件,例如:
Client
↓
DNS
↓
CDN
↓
Load Balancer
↓
Reverse Proxy / API Gateway
↓
Application Server
所以今天其實是在建立後面幾天的地基。